﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DatabaseModel;

/// <summary>
///DataImplement 的摘要说明
/// </summary>
public class DataImplement : IDataInterface
{
    private readonly DatabaseEntities _db = new DatabaseEntities();
	#region 查看商品
    /// <summary>
    /// 获得在第currentPage页上将要显示的商品
    /// currentPage从0开始计算，每页包括ItemNumOfOnePage个商品
    /// </summary>
    /// <param name="category">商品的类别</param>
    /// <param name="ItemNumOfOnePage">一个页面显示的商品个数</param>
    /// <param name="currentPage">当前在第几页，从0开始计算</param>
    /// <returns>一个商品对象列表</returns>
    /// 
    public List<Item> GetItemList(ItemCategory category, int ItemNumOfOnePage, int currentPage)///暂不实现
    {
        var categoryID = _db.ItemCategory.Where(p => p.category == category.category).FirstOrDefault();
        var model = _db.Item.Where(p => p.categoryId == categoryID.categoryId).OrderBy(p => p.itemId).Skip(currentPage * ItemNumOfOnePage).Take(ItemNumOfOnePage).ToList();
        List<Item> tmpList=new List<Item>();
        Item tmpItem;
        foreach (DatabaseModel.Item item in model)
        {
            tmpItem=new Item();
            tmpItem = GetItem(item.itemId);
            tmpList.Add(tmpItem);
        }
        return tmpList;
    }

    /// <summary>
    /// 根据关键字进行商品搜索
    /// </summary>
    /// <param name="key">key words</param>
    /// <param name="ItemNumOfOnePage">一个页面显示的商品个数</param>
    /// <param name="currentPage">当前在第几页，从0开始计算</param>
    /// <returns>一个商品对象列表</returns>
    public List<Item> GetItemListKeyWord(string key, int ItemNumOfOnePage, int currentPage)
    {
        var model = _db.Item.Where(p => p.goodName.Contains(key)).OrderBy(p=>p.itemId).Skip(currentPage * ItemNumOfOnePage).Take(ItemNumOfOnePage);
        Item tmpItem;
        List<Item> tmpList = new List<Item>();
        foreach (DatabaseModel.Item item in model)
        {
            tmpItem = new Item();
            tmpItem = GetItem(item.itemId);
            tmpList.Add(tmpItem);
        }
        return tmpList;
    }

    /// <summary>
    /// 获得编号为itemId的商品信息
    /// </summary>
    /// <param name="itemId">商品编号</param>
    /// <returns>一个商品对象</returns>
    public Item GetItem(int itemId)
    {
        var model = _db.Item.Where(p => p.itemId == itemId).FirstOrDefault();
        Item tmpItem = new Item();
        tmpItem.id = model.itemId;
        tmpItem.goodName = model.goodName;
        tmpItem.itemLocation = model.itemLocation;
        if (model.auctioneerId!=0)
        {
            tmpItem.auctioneer = getUser(Convert.ToInt32(model.auctioneerId));
        }        
        tmpItem.bidders = getBiderList(model.itemId);
        tmpItem.isCanReturn = (bool)model.isCanReturn;
        tmpItem.isSold = (bool)model.isSold;
        tmpItem.description = model.description;
        tmpItem.reservePrice = (double)model.reservePrice;
        tmpItem.shipArea = model.shipArea;
        tmpItem.shippingCost = (double)model.shippingCost;
        tmpItem.hot = (int)model.hot;
        tmpItem.closingDatetime = (DateTime)model.closingDatetime;
        tmpItem.currentPrice = (double)model.currentPrice;
        tmpItem.category = getCategory((int)model.categoryId);
        tmpItem.handingCost = (double)model.handlingConst;
        tmpItem.picAddress = model.picAddress;
        tmpItem.watchs = getWatchByItemID(model.itemId);
        tmpItem.bids = getBidByItemID(model.itemId);
        tmpItem.feedback = getFeedbackByItemID(model.itemId);
        switch (model.payMethod)
        {
            case 1:
                tmpItem.payMethod = PayMethod.VISA;
                break;
            case 2:
                tmpItem.payMethod = PayMethod.PAPER_CURRETN;
                break;
        }
        switch (model.currency)
        {
            case 1:
                tmpItem.currency = Currency.DOLLAR;
                break;
            case 2:
                tmpItem.currency = Currency.RMB;
                break;
            case 3:
                tmpItem.currency = Currency.EURO;
                break;
        }
        switch (model.condition)
        {
            case 1:
                tmpItem.condition = Condition.GOOD;
                break;
            case 2:
                tmpItem.condition = Condition.JUSTSOSO;
                break;
            case 3:
                tmpItem.condition = Condition.BAD;
                break;
        }
        return tmpItem;
    }
    #endregion

    #region  目录信息
    /// <summary>
    /// 获取所有的目录
    /// </summary>
    /// <returns>所有的目录的list</returns>
    public List<ItemCategory> GetAllItemCategory()
    {
        List<ItemCategory> tmpList = new List<ItemCategory>();
        var tmp = _db.ItemCategory;
        foreach (var itemCategory in tmp)
        {
            ItemCategory tmpI=new ItemCategory();
            tmpI = getCategory(itemCategory.categoryId);
            tmpList.Add(tmpI);
        }
        return tmpList;
    }
    #endregion

    #region  用户信息
    /// <summary>
    /// 获取当前登录的用户的基本信息
    /// 基本信息包括
    /// </summary>
    /// <param name="usrId">用户Id</param>
    /// <returns>用户对象</returns>
    public User GetUsrBasicInfo(int usrId)
    {
        User tmpUser=new User();
        tmpUser = getUser(usrId);
        return tmpUser;
    }

    /// <summary>
    /// 获取用户的WatchList
    /// 信息包括：note,Item信息()
    /// </summary>
    /// <param name="usrId">用户Id</param>
    /// <returns>用户Watch信息列表</returns>
    public List<Watch> GetAllWatchs(int usrId)
    {
        List<Watch> tmpList=new List<Watch>();
        tmpList = getWatchByUserID(usrId);
        return tmpList;
    }


    /// <summary>
    /// 获取用户所有的Bid信息
    /// 信息包括:datetime, datetime, Item(),isVectory
    /// </summary>
    /// <param name="usrId"></param>
    /// <returns></returns>
    public List<Bid> GetAllBids(int userId)
    {
        List<Bid> tmpList=new List<Bid>();
        tmpList = getBidByUserID(userId);
        return tmpList;
    }
    #endregion

    #region  feedback
    /// <summary>
    /// 获得用户的所有feedback信息，所有信息包括reply
    /// </summary>
    /// <param name="usrId">用户id</param>
    /// <returns>feebback列表</returns>
    public List<Feedback> GetAllFeedback(int userId)
    {        
        return getFeedbackByUserID(userId);
    }

    /// <summary>
    /// 添加评论
    /// </summary>
    /// <param name="bidderId">买家id</param>
    /// <param name="auctioneerId">买家id</param>
    /// <returns>是否添加成功</returns>
    public bool AddFeedback(Feedback fb)////更改
    {
        var tmp = new DatabaseModel.Feedback()
                      {
                          itemID = fb.itemId,
                          bidderId = fb.bidderId,
                          direction = fb.dir,
                          score = fb.score,
                          isWithDrawn = fb.isWithDrawn,
                          comment = fb.comment,
                          feedTime = fb.datetime,
                          reply=fb.reply_commment,
                          replyTime=fb.reply_datetime                          

                      };
        _db.Feedback.AddObject(tmp);
        _db.SaveChanges();
        return true;
    }


    /// <summary>
    /// 添加对某个feedback的回复
    /// </summary>
    /// <param name="feedbackid">feedback id</param>
    /// <returns>是否添加成功</returns>
    public bool AddReply(Feedback fb)////更改
    {
        var tmp = _db.Feedback.Where(p => p.itemID == fb.itemId && p.bidderId == fb.bidderId).FirstOrDefault();
        tmp.reply = fb.reply_commment;
        tmp.replyTime = fb.reply_datetime;
        _db.SaveChanges();
        return true;
    }
    #endregion

    #region  投标
    /// <summary>
    /// 买家对一个商品成功投标，添加这个投标，并更新其他bid的状态(原来的最高的bid被打败)
    /// </summary>
    /// <param name="usrId">买家id</param>
    /// <param name="ItemId">商品id</param>
    /// <returns>是否添加投标成功</returns>
    public bool AddBid(int usrId, int ItemId, double Price, DateTime time)//过滤
    {
        var model = _db.Bid.Where(p => p.itemId == ItemId);
        foreach (var bid in model)
        {
            bid.state = 2;
        }
        var tmp = new DatabaseModel.Bid()
                      {
                          itemId = ItemId,
                          userId = usrId,
                          price = Price,
                          bidTime = time,
                          state = 1
                          
                      };
        _db.Bid.AddObject(tmp);
        _db.SaveChanges();
        return true;
    }

    /// <summary>
    /// 修改一个bid的信息
    /// </summary>
    /// <param name="bidId">bidId</param>
    /// <param name="itemId">itemId</param>
    /// <param name="state">状态</param>
    public void setBidState(int userid, int itemId, int state)
    {
        var model =
            _db.Bid.Where(p => p.userId == userid && p.itemId == itemId).OrderByDescending(p => p.bidTime).
                FirstOrDefault();
        model.state = state;
        _db.SaveChanges();
        return;
    }

    /// <summary>
    /// 修改一个bid的状态
    /// </summary>
    /// <param name="bidId"></param>
    /// <param name="state">状态</param>
    public void setBidState(int bidId, int state)
    {
        return;
    }
    #endregion

    #region  关注商品
    /// <summary>
    /// 买家关注一个商品，添加这个Watch
    /// </summary>
    /// <param name="usrId">买家id</param>
    /// <param name="ItemId">商品id</param>
    /// <returns>是否添加Watch成功</returns>
    public bool AddWatch(int usrId, int ItemId)
    {
        var tmp = new DatabaseModel.Watch()
                      {
                          itemId = ItemId,
                          userId = usrId
                      };
        _db.Watch.AddObject(tmp);
        _db.SaveChanges();
        return true;
    }
    #endregion

    #region  拍卖
    /// <summary>
    /// 拍卖时间截止，更新商品信息
    /// </summary>
    /// <param name="itemId">商品id</param>
    /// <returns>是否更新成功</returns>
    public bool SellOutItem(int itemId)
    {
        var tmp = _db.Item.Where(p => p.itemId == itemId).FirstOrDefault();
        tmp.isSold = true;
        var model = _db.Bid.Where(p => p.itemId == itemId && p.state == 1).FirstOrDefault();
        model.state = 3;
        _db.SaveChanges();
        return true;
    }

    /// <summary>
    /// 获得胜出的买家的信息
    /// </summary>
    /// <param name="itemId">商品id</param>
    /// <returns>买到这个商品的用户对象</returns>
    public User GetVectoryBidder(int itemId)
    {
        var tmp = _db.Bid.Where(p => p.itemId == itemId).OrderByDescending(p => p.price).FirstOrDefault();
        return getUser((int) tmp.userId);
    }
    #endregion
    #region  登陆注册
    /// <summary>
    /// 用户信息是否匹配成功，用户ID和密码
    /// </summary>
    /// <param name="Id">用户ID</param>
    /// <param name="ps">用户密码</param>
    /// <returns>是否登陆成功</returns>
    public int Login(string  username, string ps)//??????????????????????????????Id or Name
    {
        User tmpUser = getUserByUserName(username);
        if( tmpUser.password == ps)
        {
            return tmpUser.userId;
        }
        else
        {
            return -1;
        }
    }

    /// <summary>
    /// 用户注册是否成功
    /// </summary>
    /// <param name="Id">用户ID</param>
    /// <param name="ps">密码</param>
    /// <param name="email">email地址</param>
    /// <returns>是否注册成功</returns>
    public int Register(string username, string ps, string email)
    {
        var tmp = new DatabaseModel.User()
                      {
                          userName = username,
                          password = ps,
                          email = email,
                          address = "-",
                          telephone = "-"
                      };
        _db.User.AddObject(tmp);
        _db.SaveChanges();
        var tmpuser = _db.User.Where(p => p.userName == username).FirstOrDefault();
        return tmpuser.userId;
    }
    #endregion

    private User getUser(int userid)
    {
        User tmpUser=new User();
        if (userid == 0)
            return null;
        var tmp = _db.User.Where(p => p.userId == userid).FirstOrDefault();
        if (tmp != null)
        {
            tmpUser.userId = tmp.userId;
            tmpUser.userName = tmp.userName;
            tmpUser.address = tmp.address;
            tmpUser.email = tmp.email;
            tmpUser.password = tmp.password;
            tmpUser.telephone = tmp.telephone;
        }

        return tmpUser;
    }
    public User getUserByUserName(string username)
    {
        User tmpUser = new User();
        var tmp = _db.User.Where(p => p.userName == username).FirstOrDefault();
        if (tmp != null)
        {
            tmpUser.userId = tmp.userId;
            tmpUser.userName = tmp.userName;
            tmpUser.address = tmp.address;
            tmpUser.email = tmp.email;
            tmpUser.password = tmp.password;
            tmpUser.telephone = tmp.telephone;
        }

        return tmpUser;
    }
    private List<User> getBiderList(int itemid)
    {
        List<User> tmpList=new List<User>();
        var tmp = _db.Bid.Where(p => p.itemId == itemid).OrderBy(p => p.bidTime);
        foreach (var bid in tmp)
        {
            User tmpUser = new User();
            tmpUser = getUser((int) bid.userId);
            tmpList.Add(tmpUser);
        }
        return tmpList;
    }
    private List<Bid> getBidByItemID(int itemid)
    {
        List<Bid> tmpList = new List<Bid>();
        var tmp = _db.Bid.Where(p => p.itemId == itemid).OrderBy(p => p.bidTime);
        foreach (var bid in tmp)
        {
            Bid tmpBid=new Bid();            
            tmpBid.datetime =Convert.ToDateTime(bid.bidTime);
            tmpBid.price =(double) bid.price;
            User tmpuser=new User();
            tmpuser.userId =(int) bid.userId;
            tmpBid.user = tmpuser;
            tmpBid.itemId = (int)bid.itemId;     
            switch (bid.state)
            {
                case 1:
                    tmpBid.state = Bid_State.NEW;
                    break;
                case 2:
                    tmpBid.state = Bid_State.FAILD;
                    break;
                case 3:
                    tmpBid.state = Bid_State.VECTORY;
                    break;
                case 4:
                    tmpBid.state = Bid_State.PAID;
                    break;
                case 5:
                    tmpBid.state = Bid_State.RECEIVED;
                    break;
            }
            tmpList.Add(tmpBid);
        }
        return tmpList;
    }
    private List<Bid> getBidByUserID(int userid)
    {
        List<Bid> tmpList = new List<Bid>();
        var tmp = _db.Bid.Where(p => p.userId == userid).OrderBy(p => p.bidTime);
        foreach (var bid in tmp)
        {
            Bid tmpBid = new Bid();
            tmpBid.datetime = Convert.ToDateTime(bid.bidTime);
            tmpBid.price = (double)bid.price;
            tmpBid.itemId = (int)bid.itemId;           
            switch (bid.state)
            {
                case 1:
                    tmpBid.state = Bid_State.NEW;
                    break;
                case 2:
                    tmpBid.state = Bid_State.FAILD;
                    break;
                case 3:
                    tmpBid.state = Bid_State.VECTORY;
                    break;
                case 4:
                    tmpBid.state = Bid_State.PAID;
                    break;
                case 5:
                    tmpBid.state = Bid_State.RECEIVED;
                    break;
            }
            tmpList.Add(tmpBid);
        }
        return tmpList;
    }
    private ItemCategory getCategory(int categoryid)
    {
        ItemCategory tmpC;
        var tmp = _db.ItemCategory.Where(p => p.categoryId == categoryid).FirstOrDefault();
        tmpC=new ItemCategory();
        tmpC.category = tmp.category;        
        return tmpC;
    }
    private List<Watch> getWatchByItemID(int itemid)
    {
        List<Watch> tmpList=new List<Watch>();
        var tmp = _db.Watch.Where(p => p.itemId == itemid);
        foreach (var watch in tmp)
        {
            Watch tmpW=new Watch();
            tmpW.user = getUser(watch.userId);
            tmpW.note = watch.note;
            tmpList.Add(tmpW);
        }
        return tmpList;
    }
    private List<Watch> getWatchByUserID(int userid)
    {
        List<Watch> tmpList = new List<Watch>();
        var tmp = _db.Watch.Where(p => p.userId == userid);
        foreach (var watch in tmp)
        {
            Watch tmpW = new Watch();
            tmpW.itemId =watch.itemId;
            tmpW.note = watch.note;
            tmpList.Add(tmpW);
        }
        return tmpList;
    }
    private List<Feedback> getFeedbackByItemID(int itemid)
    {
        List<Feedback> tmpList=new List<Feedback>();
        var tmp = _db.Feedback.Where(p => p.itemID == itemid);
        foreach (var feedback in tmp)
        {
            Feedback tmpF=new Feedback();
            tmpF.score =(int) feedback.score;
            tmpF.bidderId = feedback.bidderId;
            tmpF.comment = feedback.comment;
            tmpF.reply_commment = feedback.reply;
            tmpF.reply_datetime = (DateTime) feedback.replyTime;
            tmpF.datetime = (DateTime) feedback.feedTime;
            tmpF.isWithDrawn = (bool) feedback.isWithDrawn;
            tmpList.Add(tmpF);
        }
        return tmpList;
    }    
    private List<Feedback> getFeedbackByUserID(int userid)
    {
        List<Feedback> tmpList=new List<Feedback>();
        var tmp = _db.Feedback.Where(p => p.auctioneerId == userid);
        foreach (var feedback in tmp)
        {
            Feedback tmpF=new Feedback();
            tmpF.score =(int) feedback.score;
            tmpF.bidderId = feedback.bidderId;
            tmpF.comment = feedback.comment;
            tmpF.reply_commment = feedback.reply;
            tmpF.reply_datetime = (DateTime) feedback.replyTime;
            tmpF.datetime = (DateTime) feedback.feedTime;
            tmpF.isWithDrawn = (bool) feedback.isWithDrawn;
            tmpList.Add(tmpF);
        }
        return tmpList;
    }

    public Feedback GetFeedbackBy(int userId, int itemId, int dir)
    {
        var tmp = _db.Feedback.Where(p => p.itemID == itemId && p.auctioneerId==userId && p.direction==dir).FirstOrDefault();
        Feedback tmpF = new Feedback();
        if (tmp == null)
        {
            return tmpF;
        }
        tmpF.score = (int)tmp.score;
        tmpF.bidderId = tmp.bidderId;
        tmpF.comment = tmp.comment;
        tmpF.reply_commment = tmp.reply;
        tmpF.reply_datetime = (DateTime)tmp.replyTime;
        tmpF.datetime = (DateTime)tmp.feedTime;
        tmpF.isWithDrawn = (bool)tmp.isWithDrawn;
        return tmpF;
    }

    public List<Item> GetItemByAuctioneer(int auctioneerId)
    {
        var model = _db.Item.Where(p => p.auctioneerId == auctioneerId);
        List<Item> tmpList = new List<Item>();
        Item tmpItem;
        foreach (DatabaseModel.Item item in model)
        {
            tmpItem = new Item();
            tmpItem = GetItem(item.itemId);
            tmpList.Add(tmpItem);
        }
        return tmpList;       
    }
}
